package com.dslcode.cloud.provider.order.service;

import com.dslcode.cloud.common.dto.goods.GoodsBuyDTO;
import com.dslcode.cloud.common.dto.order.OrderCreateDTO;
import com.dslcode.cloud.common.dto.order.OrderDetailDTO;
import com.dslcode.cloud.common.dto.order.OrderPayDTO;
import com.dslcode.cloud.common.model.member.Member;
import com.dslcode.cloud.common.model.order.Order;
import com.dslcode.cloud.common.model.order.OrderCommon;
import com.dslcode.cloud.common.model.order.OrderPay;
import com.dslcode.cloud.common.utils.NullUtil;
import com.dslcode.cloud.common.utils.StringUtil;
import com.dslcode.cloud.provider.order.feign.GoodsProviderFeign;
import com.dslcode.cloud.provider.order.feign.MemberProviderFeign;
import com.dslcode.cloud.provider.order.mapper.OrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Created by dongsilin on 2017/9/21.
 */
@Slf4j
@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderPayService orderPayService;
    @Autowired
    private OrderCommonService orderCommonService;
    @Autowired
    private OrderGoodsService orderGoodsService;
    @Autowired
    private MemberProviderFeign memberProviderFeign;
    @Autowired
    private GoodsProviderFeign goodsProviderFeign;

    public List<OrderPayDTO> findAll(){
        return orderPayService.findAll();
    }

    public OrderDetailDTO findById(Long id) {
        return orderMapper.findById(id);
    }

    /**
     * 创建订单，暂时没加分布式事物
     * @param orderCreate
     * @param userId
     * @return
     */
    @Transactional
    public Order create(OrderCreateDTO orderCreate, Long userId) throws Exception {
        Set<GoodsBuyDTO> buyGoodses = orderCreate.getGoodses().parallelStream().map(g -> {
            try {
                return goodsProviderFeign.checkStorage(g.getId(), g.getBuyNum()).getResult();
            } catch (Exception e) {
                return null;
            }
        }).filter(NullUtil::isNotNull).collect(Collectors.toSet());
        if (orderCreate.getGoodses().size() > buyGoodses.size()) throw new Exception("出错啦，请稍后重试");

        // 创建OrderPay
        OrderPay orderPay = new OrderPay(userId);
        orderPayService.save(orderPay);

        // 创建Order
        Member member = memberProviderFeign.detail(userId).getResult();
        if (null == member) throw new Exception("出错啦，请稍后重试");
        log.info("member={}", member);
        BigDecimal goodsAmountTotal = buyGoodses.parallelStream().map(buyGoods -> buyGoods.getPrice().multiply(new BigDecimal(buyGoods.getBuyNum()))).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal maxFreight = buyGoodses.parallelStream().map(GoodsBuyDTO::getFreight).max((f1, f2) -> f1.compareTo(f2)).orElse(BigDecimal.ZERO);
        Order order = new Order(orderPay.getPaySn(), userId, member.getName(), goodsAmountTotal, goodsAmountTotal.add(maxFreight), maxFreight);
        orderMapper.save(order);

        // 创建OrderCommon
        OrderCommon orderCommon = orderCommonService.save(order.getId(), orderCreate.getReceiveName(), StringUtil.append2String(orderCreate.getReceiveName(), " ", orderCreate.getReceiveMobile(), " ", orderCreate.getReceiveAddress()));

        // 循环创建OrderGoods
        buyGoodses.parallelStream().forEach(buyGoods -> orderGoodsService.save(buyGoods, order));

        // 扣库存
        goodsProviderFeign.reduceStorage(buyGoodses);

        // 增加积分
        memberProviderFeign.addPoints(userId, goodsAmountTotal.intValue());

        return order;
    }

}
